#!/bin/bash
#
# Generate a CRUSH location for the given entity
#
# The CRUSH location consists of a list of key=value pairs, separated
# by spaces, all on a single line.  This describes where in CRUSH
# hierarhcy this entity should be placed.
#
# Arguments:
#   --cluster <clustername>   name of the cluster (see /etc/ceph/$cluster.conf)
#   --type <osd|mds|client>   daemon/entity type
#   --id <id>                 id (osd number, mds name, client name)
#

# if we start up as ./ceph-crush-location, assume everything else is
# in the current directory too.
if [ `dirname $0` = "." ] && [ $PWD != "/usr/bin" ]; then
    BINDIR=.
    SBINDIR=.
    LIBDIR=.
    ETCDIR=.
else
    BINDIR=/usr/bin
    SBINDIR=/usr/sbin
    LIBDIR=/usr/lib/ceph
    ETCDIR=/etc/ceph
fi

usage_exit() {
    echo "usage: $0 [--cluster <cluster>] --id <id> --type <osd|mds|client>"
    exit
}

#HOST_AZ="
#{% for h in groups['ceph'] %}
#ceph{{ loop.index0 }},NA,REPLICA0{{ loop.index }},{{ root_name }}
#{% endfor %}
#"

HOST_AZ="
{% for h in groups['ceph'] %}
{{ hostvars[h]['hostname'] }},NA,REPLICA0{{ loop.index }},{{ root_name }}
{% endfor %}
"

get_az() {
    for line in $HOST_AZ
    do
        host=$(echo $line |awk -F"[, ]" '{print $1}')
        az=$(echo $line |awk -F"[, ]" '{print $3}')

        h=$(hostname -s)
        if [ X"$host" == X"$h" ] ;then
            echo $az
        fi
    done
}

get_switch() {
    for line in $HOST_AZ
    do
        local host=$(echo $line |awk -F"[, ]" '{print $1}')
        local switch=$(echo $line |awk -F"[, ]" '{print $4}')

        h=$(hostname -s)
        if [ X"$host" == X"$h" ] ;then
            echo $switch
        fi
    done
}

get_osd_location() {
    myaz=$(get_az)
    sw=$(get_switch)
    echo "root=${sw} chassis=${sw}_${myaz} host=$(hostname -s)"
}

cluster="ceph"
type=""
id=""
while [ $# -ge 1 ]; do
    case $1 in
    --cluster | -C)
        shift
        cluster="$1"
        shift
        ;;
    --id | -i)
        shift
        id="$1"
        shift
        ;;
    --type | -t)
        shift
        type="$1"
        shift
        ;;
    *)
        echo "unrecognized option '$1'"
        usage_exit
        ;;
    esac
done

if [ -z "$type" ]; then
    echo "must specify entity type"
    usage_exit
fi

if [ -z "$id" ]; then
    echo "must specify id"
    usage_exit
fi

# try a type-specific config, e.g. 'osd crush location'
location="$($BINDIR/ceph-conf --cluster=${cluster:-ceph} --name=$type.$id --lookup ${type}_crush_location || :)"
if [ -n "$location" ]; then
    echo $location
    exit 0
fi

# try a generic location
location="$($BINDIR/ceph-conf --cluster=${cluster:-ceph} --name=$type.$id --lookup crush_location || :)"
if [ -n "$location" ]; then
    echo $location
    exit 0
fi

if [ "$type" == "osd" ];then
    get_osd_location $id
    exit 0
else
    # spit out something generic
    echo "host=$(hostname -s) root=default"
fi
